﻿using System;
using System.Collections;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;
using System.Text;
using System.Net;
using System.ComponentModel;
using System.Net.Mail;


    public class Clientes
    {
        public DBClientes dbClientes;
        public int codigoCliente;
        public String localidade;
        public String username;
        public String password;
        public String nome;
        public DateTime dataNascimento;
        public String rua;
        public String codigoPostal;
        public String bi;
        public String nif;
        public String mail;
        public int pontosTotais;
        public int pontosGastos;
        public bool estadoConta;
        public double latitude;
        public double longitude;
        public String sexo;
        public ArrayList telefones;

        public Clientes(System.Data.Odbc.OdbcConnection con)
        {
            dbClientes = new DBClientes(con);
            
        }

        
        
        public Hashtable pedirListaClientes()
        {
            return dbClientes.obterListaClientes();
        }

        public void pedirDadosCliente()
        {
            dbClientes.obterDadosCliente(username, this);
        }

        public void desactivarConta()
        {
            dbClientes.desactivarConta(username);
        }

        public bool existeVotoClienteFilme(String filme,String ano)
        {
            //não esquecer que "username" tem de estar definido antes de verificar o voto
            return dbClientes.existeVotoClienteFilme(username, filme,ano);
        }

        public void alterarVoto(int voto,String filme, String ano)
        {
            dbClientes.alterarVoto(username, filme, ano, voto);
        }
        public void alterarVoto(int voto, String filme, String ano)
        {
            dbClientes.novoVoto(username, filme, ano, voto);
        }
        
        public void pedirLocalizacao()
        {
            dbClientes.obterCoordenadas(username,this);
        }
        
        public void actualizarPontosCliente()
        {
            dbClientes.actualizarPontosCliente(username);
        }
       
        public bool verificarPassword(String pass)
        {
            password = pass;
            return dbClientes.verificarPassword(username, pass);
        }
        
        public void desactivarConta()
        {
            dbClientes.desactivarConta(username);
        }
        
        public void pedirDados()
        {
            dbClientes.obterDadosCliente(username,this);
        }
        
        public static bool formatoValido(String email)
        {
            if (email == null)
            {
                return false;
            }
            return Regex.IsMatch(email, @"^[-a-zA-Z0-9][-.a-zA-Z0-9]*@[-.a-zA-Z0-9]+(\.[-.a-zA-Z0-9]+)*\.(com|edu|info|gov|int|mil|net|org|biz|name|museum|coop|aero|pro|[a-zA-Z]{2})$",RegexOptions.IgnorePatternWhitespace);     
        }
        
        public bool verificarEmail(String email)
        {
            if(dbClientes.verificarEmail(email))
            {
                mail=email;
                return true;
            }else return false;
        }
        
        public void actualizarDadosCliente()
        {
            dbClientes.actualizarDadosCliente(username, rua, codigoPostal, mail, latitude, longitude, telefones);
            
        }
        
        public bool verificarUsernameEMail(String user, String email)
        {
            return dbClientes.verificarUsernameEmail(user, email);
        }
         
        
        private int RandomNumber(int min, int max)
        {
            Random random = new Random();
            return random.Next(min, max);
        }

        private string RandomString(int size, bool lowerCase)
        {
            StringBuilder builder = new StringBuilder();
            Random random = new Random();
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }
            if (lowerCase)
                return builder.ToString().ToLower();
            return builder.ToString();
        }

        private String gerarPassUsername()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(RandomString(4, true));
            builder.Append(RandomNumber(1000, 9999));
            builder.Append(RandomString(2, false));
            return builder.ToString();
        }

        private bool enviarMail(String toMail,String subject, String body)
        {
            
            //Falta pôr por proxy
            
           string host="smtp.gmail.com";
            int port=587;
            string mailUsername = "cinescope.mail@gmail.com";
            string mailPassword="csmpassword";
            string fromAddress=mailUsername;
            bool sslEnabled=true;
        

            /*
             * NOTA:::::::::::::::::::::::::::::::::::::::::
             * Como enviar para vários ao mesmo tempo:
             * MailMessage msg = new MailMessage();
             * msg.To.Add(new MailAddress("me@here.now"));
             * msg.To.Add(new MailAddress("you@there.now"));
             */
            
            MailMessage msg = new MailMessage(new MailAddress(fromAddress), new MailAddress(toMail));    //  Create a MailMessage object with a from and to address
            msg.Subject = subject;  //  Add your subject
            msg.SubjectEncoding = System.Text.Encoding.UTF8;
            msg.Body = body;    //  Add the body of your message
            msg.BodyEncoding = System.Text.Encoding.UTF8;
            msg.IsBodyHtml = false; //  Does the body contain html

            SmtpClient client = new SmtpClient(host, port); //  Create an instance of SmtpClient with your smtp host and port
            client.Credentials = new NetworkCredential(mailUsername, mailPassword); //  Assign your username and password to connect to gmail
            client.EnableSsl = sslEnabled;  //  Enable SSL

            try
            {
                client.Send(msg);   //  Try to send your message
               // ShowMailMessage("Your message was sent successfully.", false);  //  A method to update a ui element with a message
                return true;
            }
            catch (SmtpException ex)
            {
                //ShowMailMessage(string.Format("There was an error sending you message. {0}", ex.Message), true);
                return false;
            }

        }
        
        public bool gerarPass()
        {
            password = gerarPassUsername();
            dbClientes.actualizarPassword(username, password);

            StringBuilder sb = new StringBuilder();
            sb.Append("---- Este email foi enviado automaticamente ----\n");
            sb.Append("Recebeu este email porque foi requisitada uma nova password de acesso à sua conta do CineScope.\nSeguem-se os dados actualizados.\n\n");
            sb.Append("Utilizador: ");
            sb.Append(username);
            sb.Append("\nNova password: ");
            sb.Append(password);
            sb.Append("\n----Não utilizar este email para contacto----");
            return enviarMail(mail,"[CineScope] Nova password",sb.ToString());
        }
        
        public bool verificarUsername(String user)
        {
            return dbClientes.verificarUsername(user);
        }
         
        
        public static bool isEqual(String p1, String p2)
        {
            return p1.Equals(p2);
        }
        
        public static bool isNull(String s)
        {
            if(s==null || s.Length<=0)
                return true;
            return false;
        }
        
        public bool verificarEMailAmigo(String emailAmigo)
        {
            return dbClientes.verificarEmailAmigo(emailAmigo);
        }
         
        
        public bool adicionarPontosAmigo(String toMail)
        {
            dbClientes.adicionarPontos(toMail);
             StringBuilder sb = new StringBuilder();
            sb.Append("---- Este email foi enviado automaticamente ----\n");
            sb.Append("Parabéns!\n\nO utilizador \"");
            sb.Append(username);
            sb.Append("\" inscreveu-se no CineScope com o mail \"");
            sb.Append(mail);
            sb.Append("\", e isso significa que ganhaste pontos de cliente.\n\n");
            sb.Append("Lembra-te: Mais convites = mais pontos, por isso convida já todos os teus amigos!");
            sb.Append("\n----Não utilizar este email para contacto----");
            return enviarMail(toMail, "[CineScope] Mais amigos, mais pontos", sb.ToString());
        }
        
        public bool verificarDadosPessoais()
        {
            return true;
            //método redundante, apenas para cumprir especificações
        }
        
        public void registarDadosCliente()
        {
            dbClientes.registarDadosCliente(username, localidade, password, nome, dataNascimento, rua, codigoPostal, bi, nif, mail, latitude, longitude, sexo, telefones);
        }
        
        public bool verificarUsernamePassword(String user, String pass)
        {
            username = user;
            password = pass;
            return dbClientes.verificarPassword(user, pass);
        }

        public bool verificarPontosSuficientes(int pontos_premio)
        {
            return dbClientes.verificarPontosSuficientes(username, pontos_premio);
        }
         

        public bool retirarPontosCliente(String premio, int pontos)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("---- Este email foi enviado automaticamente ----\n");
            sb.Append("Parabéns!\n\nFoi efectuado com sucesso o resgate do prémio \"");
            sb.Append(premio);
            sb.Append("\" pelo total de \"");
            sb.Append(pontos);
            sb.Append("\" pontos.\n Após o processamento da informação, receberás um email com instruções de como proceder ao levantamento do prémio.\n\n");
            sb.Append("Lembra-te: Mais convites = mais pontos, por isso convida já todos os teus amigos!");
            sb.Append("\n----Não utilizar este email para contacto----");
            dbClientes.retirarClientePontos(username, pontos);
            return enviarMail(mail, "[CineScope] Resgate de Premio", sb.ToString());
            
        }

        public bool enviarConvite(String mail_amigo)
        {
            StringBuilder sbs = new StringBuilder();
            sbs.Append("Convite de ");
            sbs.Append(username);
            sbs.Append(" para participar no CineScope");
            StringBuilder sb = new StringBuilder();
            sb.Append("---- Este email foi enviado automaticamente ----\n");
            sb.Append("Parabéns!\n\nFoste convidado para te inscreveres no CineScope.\nAo Completares a inscrição, se referires o teu amigo \"");
            sb.Append(username);
            sb.Append("\" (");
            sb.Append(mail);
            sb.Append(") ele receberá pontos dedutiveis em prémios.\nDepois de te inscreveres, podes tu também convidar amigos para se inscreverem, de forma a ganhares prémios através das referências deles!");
            sb.Append("Até já. :)");
            sb.Append("\n----Não utilizar este email para contacto----");
            return enviarMail(mail_amigo, sbs.ToString(), sb.ToString());
        }
    }